package nc.impl.hrppl.proupdate.proupdatehvo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import nc.bs.dao.BaseDAO;
import nc.impl.hrppl.pjapplication.pjappl.SJXMUtil;
import nc.itf.hrppl.pjapplication.IUapbdFourCGProjectService;
import nc.itf.hrppl.pjapplication.IUapbdFourProjectService;
import nc.vo.pub.ISuperVO;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.framework.common.NCLocator;
import nc.codeplatform.framework.service.ServiceSupport;
import nc.itf.hrppl.proupdate.proupdatehvo.IProUpdateHVOService;
import nc.jdbc.framework.processor.ColumnProcessor;
import nc.pub.billcode.vo.BillCodeContext;
import nc.pubitf.para.SysInitQuery;
import nc.vo.hrppl.proupdate.AggProUpdateHVO;
import nc.vo.hrppl.proupdate.CGUpdateCVO;
import nc.vo.hrppl.proupdate.ProUpdateBVO;
import nc.vo.hrppl.proupdate.ProUpdateCVO;
import nc.vo.hrppl.proupdate.ProUpdateHVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.SuperVO;
import nc.vo.pub.VOStatus;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pub.lang.UFDate;
import nc.vo.pub.lang.UFDateTime;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pub.pf.BillStatusEnum;
import nccloud.framework.core.exception.ExceptionUtils;

public class ProUpdateHVOServiceImpl extends ServiceSupport implements IProUpdateHVOService {

	@Override
	public AggProUpdateHVO[] listAggProUpdateHVOByPk(String... pks) throws BusinessException {
		return listAggProUpdateHVOByPk(false, pks);
	}

	@Override
	public AggProUpdateHVO[] listAggProUpdateHVOByPk(boolean blazyLoad, String... pks) throws BusinessException {
		return dao.listByPksWithOrder(AggProUpdateHVO.class, pks, blazyLoad);
	}

	@Override
	public AggProUpdateHVO findAggProUpdateHVOByPk(String pk) throws BusinessException {
		return dao.findByPk(AggProUpdateHVO.class, pk, false);
	}

	@Override
	public AggProUpdateHVO[] listAggProUpdateHVOByCondition(String condition) throws BusinessException {
		return listAggProUpdateHVOByCondition(condition, new String[] { "pk_proupdate" });
	}

	@Override
	public AggProUpdateHVO[] listAggProUpdateHVOByCondition(String condition, String[] orderPath)
			throws BusinessException {
		return dao.listByCondition(AggProUpdateHVO.class, condition, false, false, orderPath);
	}

	@Override
	public ProUpdateHVO[] listProUpdateHVOByPk(String... pks) throws BusinessException {
		return dao.listByPk(ProUpdateHVO.class, pks, true);
	}

	@Override
	public ProUpdateHVO findProUpdateHVOByPk(String pk) throws BusinessException {
		return dao.findByPk(ProUpdateHVO.class, pk, true);
	}

	@Override
	public ProUpdateHVO[] listProUpdateHVOByCondition(String condition) throws BusinessException {
		return listProUpdateHVOByCondition(condition, new String[] { "pk_proupdate" });
	}

	@Override
	public ProUpdateHVO[] listProUpdateHVOByCondition(String condition, String[] orderPath) throws BusinessException {
		return dao.listByCondition(ProUpdateHVO.class, condition, false, false, orderPath);
	}

	@Override
	public String[] listProUpdateHVOPkByCond(String condition) throws BusinessException {
		return listProUpdateHVOPkByCond(condition, new String[] { " billdate desc " });
	}

	@Override
	public String[] listProUpdateHVOPkByCond(String condition, String[] orderPath) throws BusinessException {
		if (StringUtils.isEmpty(condition)) {
			condition = " 1 = 1 ";
		}
		StringBuilder sql = new StringBuilder();
		sql.append(" select pk_proupdate from ").append(ProUpdateHVO.getDefaultTableName());
		sql.append(" where ").append(condition);
		if (ArrayUtils.isNotEmpty(orderPath)) {
			sql.append(" order by ").append(StringUtils.join(orderPath, ", "));
		}
		return (String[]) dao.getBaseDAO().executeQuery(sql.toString(), (rs) -> {
			List<String> pks = new ArrayList<>();
			while (rs.next()) {
				pks.add(rs.getString(1));
			}
			return pks.toArray(new String[0]);
		});
	}

	@Override
	public void initDefaultData(ProUpdateHVO vo) {
		if (vo.getAttributeValue("pk_group") == null) {
			vo.setAttributeValue("pk_group", InvocationInfoProxy.getInstance().getGroupId());
		}
		if (vo.getAttributeValue("billmaker") == null) {
			vo.setAttributeValue("billmaker", InvocationInfoProxy.getInstance().getUserId());
		}
		if (vo.getAttributeValue("maketime") == null) {
			vo.setAttributeValue("maketime", new UFDateTime(InvocationInfoProxy.getInstance().getBizDateTime()));
		}
		if (vo.getAttributeValue("billdate") == null) {
			vo.setAttributeValue("billdate", new UFDate(InvocationInfoProxy.getInstance().getBizDateTime()));
		}
		if (vo.getAttributeValue("billtype") == null) {
			vo.setAttributeValue("billtype", "PL02");
		}
		if (vo.getAttributeValue("approvestatus") == null) {
			vo.setAttributeValue("approvestatus", BillStatusEnum.FREE.toIntValue());
		}
	}

	@Override
	public AggProUpdateHVO preAddAggProUpdateHVO(AggProUpdateHVO vo, Map<String, Object> userJson)
			throws BusinessException {

		getMainVO(vo).setStatus(VOStatus.NEW);
		initDefaultData((ProUpdateHVO) getMainVO(vo));

		// 下面这段要判断是否是树表界面插件
		Map<String, String> data = userJson != null && userJson.get("data") != null
				? (Map<String, String>) userJson.get("data")
				: null;
		if (data != null && data.size() > 0) {
			String parentKey = data.get("parentKey");
			String parentPk = data.get("parentPk");
			getMainVO(vo).setAttributeValue(parentKey, parentPk);
		}

		// 编码规则生成vo的编码
		BillCodeContext billCodeContext = getBillCodeContext("hrpplproupdate");
		if (billCodeContext == null) {
			throw new BusinessException("当前编码规则不存在，请到【编码规则定义-全局】节点检查是否存在" + "hrpplproupdate");
		}
		if (billCodeContext.isPrecode()) {
			String pk_group = InvocationInfoProxy.getInstance().getGroupId();
			String code = getBillcodeManage().getPreBillCode_RequiresNew("hrpplproupdate", pk_group, pk_group);
			getMainVO(vo).setAttributeValue("billno", code);
		}

		return vo;
	}

	@Override
	public AggProUpdateHVO preAddAggProUpdateHVO(Map<String, Object> userJson) throws BusinessException {
		AggProUpdateHVO result = null;

		ProUpdateHVO mainvo = new ProUpdateHVO();
		// 设置默认值
		initDefaultData(mainvo);
		AggProUpdateHVO aggvo = new AggProUpdateHVO();
		aggvo.setParent(mainvo);
		result = aggvo;
		return preAddAggProUpdateHVO(result, userJson);
	}

	@Override
	public AggProUpdateHVO preEditAggProUpdateHVO(String pk) throws BusinessException {
		return dao.findByPk(AggProUpdateHVO.class, pk, false);
	}

	@Override
	public AggProUpdateHVO copyAggProUpdateHVO(String pk) throws BusinessException {

		AggProUpdateHVO vo = dao.findByPk(AggProUpdateHVO.class, pk, false);

		getMainVO(vo).setPrimaryKey(null);
		getMainVO(vo).setStatus(VOStatus.NEW);

		getMainVO(vo).setAttributeValue("srcbilltype", null);
		getMainVO(vo).setAttributeValue("srcbillid", null);

		getMainVO(vo).setAttributeValue("billno", null);
		getMainVO(vo).setAttributeValue("", null);
		// 编码规则生成vo的编码
		BillCodeContext billCodeContext = getBillCodeContext("hrpplproupdate");
		if (billCodeContext == null) {
			throw new BusinessException("当前编码规则不存在，请到【编码规则定义-全局】节点检查是否存在" + "hrpplproupdate");
		}
		if (billCodeContext.isPrecode()) {
			String pk_group = InvocationInfoProxy.getInstance().getGroupId();
			String code = getBillcodeManage().getPreBillCode_RequiresNew("hrpplproupdate", pk_group, pk_group);
			getMainVO(vo).setAttributeValue("billno", code);
		}
		getMainVO(vo).setAttributeValue("approvestatus", BillStatusEnum.FREE.toIntValue());
		getMainVO(vo).setAttributeValue("billmaker", InvocationInfoProxy.getInstance().getUserId());
		getMainVO(vo).setAttributeValue("approver", null);
		getMainVO(vo).setAttributeValue("approvenote", null);
		getMainVO(vo).setAttributeValue("approvedate", null);
		// 设置审计信息为空
		getMainVO(vo).setAttributeValue("creator", null);
		getMainVO(vo).setAttributeValue("creationtime", null);
		getMainVO(vo).setAttributeValue("modifier", null);
		getMainVO(vo).setAttributeValue("modifiedtime", null);
		getMainVO(vo).setAttributeValue("maketime", new UFDateTime(InvocationInfoProxy.getInstance().getBizDateTime()));

		ProUpdateCVO[] proUpdateCVOs = (ProUpdateCVO[]) vo.getChildren(ProUpdateCVO.class);
		if (proUpdateCVOs != null && proUpdateCVOs.length > 0) {
			Arrays.stream(proUpdateCVOs).forEach(subvo -> {
				subvo.setPrimaryKey(null);
				subvo.setStatus(VOStatus.NEW);
				subvo.setAttributeValue("srcbilltype", null);
				subvo.setAttributeValue("srcbillid", null);
				subvo.setAttributeValue("rowno", null);
				subvo.setAttributeValue("", null);
			});
		}
		ProUpdateBVO[] proUpdateBVOs = (ProUpdateBVO[]) vo.getChildren(ProUpdateBVO.class);
		if (proUpdateBVOs != null && proUpdateBVOs.length > 0) {
			Arrays.stream(proUpdateBVOs).forEach(subvo -> {
				subvo.setPrimaryKey(null);
				subvo.setStatus(VOStatus.NEW);
				subvo.setAttributeValue("srcbilltype", null);
				subvo.setAttributeValue("srcbillid", null);
				subvo.setAttributeValue("rowno", null);
				subvo.setAttributeValue("srcrowno", null);
			});
		}
		CGUpdateCVO[] cgUpdateBVOs = (CGUpdateCVO[]) vo.getChildren(CGUpdateCVO.class);
		if (cgUpdateBVOs != null && cgUpdateBVOs.length > 0) {
			Arrays.stream(cgUpdateBVOs).forEach(subvo -> {
				subvo.setPrimaryKey(null);
				subvo.setStatus(VOStatus.NEW);
				subvo.setAttributeValue("srcbilltype", null);
				subvo.setAttributeValue("srcbillid", null);
				subvo.setAttributeValue("rowno", null);
				subvo.setAttributeValue("srcrowno", null);
			});
		}
		return vo;
	}

	@Override
	public AggProUpdateHVO[] saveAggProUpdateHVO(AggProUpdateHVO vo) throws BusinessException {
		String pk = getVOPrimaryKey(vo);

		// 进行一些校验
		// 1.同一个项目不能存在多个未审核通过的单据
		ProUpdateHVO parentVO = vo.getParentVO();
		if (StringUtils.isEmpty(pk)) { // 新增
			ProUpdateHVO[] proUpdateHVOs = listProUpdateHVOByCondition(
					" pk_proapp = '" + parentVO.getPk_proapp() + "'");

			if (proUpdateHVOs != null && proUpdateHVOs.length > 0) {
				boolean flag = false;
				for (int i = 0; i < proUpdateHVOs.length; i++) {
					Integer approvestatus = proUpdateHVOs[i].getApprovestatus();
                    if (approvestatus != 1) {
                        flag = true;
                        break;
                    }
				}
				if (flag) {
					throw new BusinessException("同一个项目不能存在多个未审核通过的单据");
				}
			}
		}
		UFBoolean HRPXM006_Boolean = SysInitQuery.getParaBoolean(vo.getParentVO().getPk_group(), "HRPXM006");
		if (HRPXM006_Boolean.booleanValue()) {
			if (StringUtils.isNotEmpty(parentVO.getBelongpro())) {
				
				UFDouble father_data = UFDouble.ZERO_DBL;
				Object father = dao.getBaseDAO().executeQuery(" SELECT PJTOTALCOST FROM HRPPL_PJAPPL WHERE  PK_PJAPPL = '"+parentVO.getBelongpro()+"' ",new ColumnProcessor());
				if (father != null) {
					father_data = new UFDouble(String.valueOf(father));
					UFDouble updallfun = parentVO.getUpdallfun();
					
					UFDouble total_data = UFDouble.ZERO_DBL;
					Object total = dao.getBaseDAO().executeQuery(" SELECT SUM(PJTOTALCOST) total FROM HRPPL_PJAPPL WHERE BELONGPRO = '"
							+ parentVO.getBelongpro() + "' AND PK_PJAPPL != '"+parentVO.getPk_proapp()+"' ", new ColumnProcessor());
					if (total != null) {
						total_data = new UFDouble(String.valueOf(total));
					}
					UFDouble result = updallfun.add(total_data).sub(father_data);
					if (result.doubleValue() > 0) {
						throw new BusinessException("当前单据父项目的所有子项目经费总和已超过父项目总经费:"+new UFDouble(result.doubleValue(),2)+"元");
					}
				}
			}
		}

		setDefaultVal(vo);
		if (StringUtils.isEmpty(pk)) {
			return dao.insert(vo); // 插入
		} else {
			return dao.update(vo); // 更新
		}
	}

	/**
	 * 保存前处理编码规则
	 * 
	 * @param vos
	 */
	private void setBillCode(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isNotEmpty(vos)) {
			for (AggProUpdateHVO vo : vos) {
				String pk = getVOPrimaryKey(vo);
				if (StringUtils.isEmpty(pk)) {
					BillCodeContext billCodeContext = getBillCodeContext("hrpplproupdate");
					String pk_group = InvocationInfoProxy.getInstance().getGroupId();
					if (billCodeContext != null && !billCodeContext.isPrecode()) {
						if (getMainVO(vo).getAttributeValue("billno") == null) {
							String code = getBillcodeManage().getBillCode_RequiresNew("hrpplproupdate", pk_group,
									pk_group, getMainVO(vo));
							getMainVO(vo).setAttributeValue("billno", code);
						}
					} else {
						String code = (String) getMainVO(vo).getAttributeValue("billno");
						getBillcodeManage().commitPreBillCode("hrpplproupdate", pk_group, pk_group, code);
					}
				}
			}
		}
	}

	/**
	 * 保存前设置审计信息
	 * 
	 * @param vos
	 */
	private void setAuditInfo(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isNotEmpty(vos)) {
			UFDateTime now = new UFDateTime();
			for (AggProUpdateHVO vo : vos) {
				String pk = getVOPrimaryKey(vo);
				if (StringUtils.isEmpty(pk)) {
					// 设置创建人创建时间
					getMainVO(vo).setAttributeValue("creator", InvocationInfoProxy.getInstance().getUserId());
					getMainVO(vo).setAttributeValue("creationtime", now);
					getMainVO(vo).setAttributeValue("maketime", now);
					getMainVO(vo).setAttributeValue("billmaker", InvocationInfoProxy.getInstance().getUserId()); // 制单人
					getMainVO(vo).setAttributeValue("modifier", null);
					getMainVO(vo).setAttributeValue("modifiedtime", null);
				} else {
					// 设置修改人修改时间
					getMainVO(vo).setAttributeValue("modifier", InvocationInfoProxy.getInstance().getUserId());
					getMainVO(vo).setAttributeValue("modifiedtime", now);
					getMainVO(vo).setAttributeValue("lastmaketime", now);
				}
			}
		}
	}

	/**
	 * 保存前处理一些默认值
	 * 
	 * @param vos
	 */
	private void setDefaultVal(AggProUpdateHVO... vos) throws BusinessException {
		setBillCode(vos);
		setAuditInfo(vos);
		// 其他默认值处理
	}

	// 给单表（行编辑表）单独适配
	@Override
	public AggProUpdateHVO[] saveAggProUpdateHVO(AggProUpdateHVO[] vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return new AggProUpdateHVO[0];
		}
		setDefaultVal(vos); // 设置默认值
		List<String> pks = Arrays.stream(vos).filter(v -> getMainVO(v).getStatus() == VOStatus.DELETED)
				.map(v -> getMainVO(v).getPrimaryKey()).collect(Collectors.toList()); // 删除单据主键
		if (pks == null || pks.size() == 0) {
			return dao.save(vos, true);
		}
		AggProUpdateHVO[] deleteVOs = dao.listByPk(AggProUpdateHVO.class, pks.toArray(new String[0]));
		for (int i = 0; i < deleteVOs.length; i++) {
			SuperVO mainVO = getMainVO(deleteVOs[i]);
			// 删除单据时校验单据状态
			Integer approveStatus = (Integer) mainVO.getAttributeValue("approvestatus");
			if (approveStatus != null && !approveStatus.equals(-1)) {
				throw new BusinessException("第" + (i + 1) + "张单据处理失败：单据状态不正确，不能删除！");
			}
			// 删除单据时回退单据号
			String code = (String) mainVO.getAttributeValue("billno");
			if (StringUtils.isNotEmpty(code)) {
				String pk_group = InvocationInfoProxy.getInstance().getGroupId();
				getBillcodeManage().returnBillCodeOnDelete("hrpplproupdate", pk_group, pk_group, code, deleteVOs[i]);
			}
		}
		return dao.save(vos, true);
	}

	@Override
	public AggProUpdateHVO[] deleteAggProUpdateHVOs(Map<String, String> tsMap) throws BusinessException {
		AggProUpdateHVO[] vos = dao.listByPk(AggProUpdateHVO.class, tsMap.keySet().toArray(new String[0]));
		validate(vos, tsMap);
		String pk_group = InvocationInfoProxy.getInstance().getGroupId();
		Arrays.stream(vos).forEach(vo -> {
			String code = (String) getMainVO(vo).getAttributeValue("billno");
			try {
				getBillcodeManage().returnBillCodeOnDelete("hrpplproupdate", pk_group, pk_group, code, vo);
			} catch (BusinessException e) {
				ExceptionUtils.wrapException(e.getMessage(), e);
			}
		});
		dao.delete(vos, true);
		return vos;
	}

	// 校验 包括ts校验 已提交校验
	private void validate(AggProUpdateHVO[] vos, Map<String, String> tsMap) throws BusinessException {

		Boolean isPass = true;
		String error = ""; // 错误信息
		if (ArrayUtils.isEmpty(vos)) {
			isPass = false;
		}

		for (int i = 0; i < vos.length; i++) {
			SuperVO mainvo = vos[i].getParentVO();
			UFDateTime ts = (UFDateTime) mainvo.getAttributeValue("ts");
			if (!StringUtils.equals(tsMap.get(mainvo.getPrimaryKey()), ts.toString())) {
				isPass = false;
				break;
			}
			Integer approvestatus = (Integer) mainvo.getAttributeValue("approvestatus");
			if (approvestatus == null || approvestatus != BillStatusEnum.FREE.toIntValue()) {
				error += "第" + (i + 1) + "张单据处理失败：审批状态不正确，不能删除！\n";
			}
		}
		if (!isPass) {
			throw new BusinessException("您操作的数据已被他人修改或删除，请刷新后重试！");
		}
		if (!"".equals(error)) {
			throw new BusinessException(error);
		}
	}

	@Override
	public <T> T[] loadTreeData(Class<T> clazz, Map<String, Object> userJson) throws BusinessException {
		String condition = "dr = 0 ";
		return dao.listByCondition(clazz, condition, false);
	}

	@Override
	public String[] queryChildPksByParentId(Class childClazz, String parentId) throws BusinessException {
		String cond = " pk_proupdate = '" + parentId + "' ";
		SuperVO[] vos = (SuperVO[]) dao.listByCondition(childClazz, cond, false);
		if (vos == null || vos.length == 0) {
			return new String[0];
		}
		return Stream.of(vos).map(vo -> vo.getPrimaryKey()).toArray(String[]::new);
	}

	public SuperVO[] queryChildVOByPks(Class childClazz, String[] pks) throws BusinessException {
		return (SuperVO[]) dao.listByPk(childClazz, pks, false);
	}

	/**
	 * 提交前校验: 检查单据状态
	 * 
	 * @throws BusinessException
	 */
	private void validateCommitAggProUpdateHVO(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return;
		}
		List<AggProUpdateHVO> list = Arrays.stream(vos).filter(item -> item.getParentVO() != null).filter(item -> {
			Integer status = (Integer) item.getParentVO().getAttributeValue("approvestatus");
			return status == null
					|| status != BillStatusEnum.FREE.toIntValue() && status != BillStatusEnum.NOPASS.toIntValue();
		}).map(item -> item).collect(Collectors.toList());
		if (list == null || list.size() == 0) {
			return;
		}
		String errors = "";
		for (AggProUpdateHVO vo : list) {
			errors += "单据号：[" + vo.getParentVO().getAttributeValue("billno") + "]提交失败，失败原因：单据状态不正确，请检查。\n";
		}
		throw new BusinessException(errors);
	}

	/**
	 * 收回前校验: 检查单据状态
	 * 
	 * @throws BusinessException
	 */
	private void validateUnCommitAggProUpdateHVO(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return;
		}
		List<AggProUpdateHVO> list = Arrays.stream(vos).filter(item -> item.getParentVO() != null).filter(item -> {
			Integer status = (Integer) item.getParentVO().getAttributeValue("approvestatus");
			return status == null || status == BillStatusEnum.FREE.toIntValue();
		}).map(item -> item).collect(Collectors.toList());
		if (list == null || list.size() == 0) {
			return;
		}
		String errors = "";
		for (AggProUpdateHVO vo : list) {
			errors += "单据号：[" + vo.getParentVO().getAttributeValue("billno") + "]收回失败，失败原因：单据状态不正确，请检查。\n";
		}
		throw new BusinessException(errors);
	}

	@Override
	public Object commitAggProUpdateHVO(String actionName, Map<String, String> tsMap, Object assign)
			throws BusinessException {
		AggProUpdateHVO[] vos = dao.listByPk(AggProUpdateHVO.class, getAllPks(tsMap), false);
		validateTs(tsMap, vos);
		// 提交前校验及业务逻辑
		validateCommitAggProUpdateHVO(vos);
		// modify by wy
		SJXMUtil.commitAggProUpdateHVO(vos);
		Map<String, Object> res = this.execFlows(actionName, "PL02", assign, vos);
		// 提交后业务逻辑
		return res;
	}
	@Override
	public Object batchCommitAggProUpdateHVO(String actionName, Map<String, String> tsMap) throws BusinessException {
		AggProUpdateHVO[] vos = dao.listByPk(AggProUpdateHVO.class, getAllPks(tsMap), false);
		validateTs(tsMap, vos);
		// 批量提交前校验及业务逻辑
		validateCommitAggProUpdateHVO(vos);
		Map<String, Object> res = this.execFlows(actionName, "PL02", vos);
		// 批量提交后业务逻辑
		return res;
	}

	@Override
	public Object uncommitAggProUpdateHVO(String actionName, Map<String, String> tsMap) throws BusinessException {
		AggProUpdateHVO[] vos = dao.listByPk(AggProUpdateHVO.class, getAllPks(tsMap), false);
		validateTs(tsMap, vos);
		// 收回前校验及业务逻辑
		validateUnCommitAggProUpdateHVO(vos);
		// 回写采购四级项目
		// modif by wy
		SJXMUtil.UnCommitAggProUpdateHVO(vos);
		Map<String, Object> res = this.execFlows(actionName, "PL02", vos);

		// 收回后业务逻辑
		return res;
	}

	@Override
	public Object batchUncommitAggProUpdateHVO(String actionName, Map<String, String> tsMap) throws BusinessException {
		AggProUpdateHVO[] vos = dao.listByPk(AggProUpdateHVO.class, getAllPks(tsMap), false);
		validateTs(tsMap, vos);
		// 批量收回前校验及业务逻辑
		validateUnCommitAggProUpdateHVO(vos);
		Map<String, Object> res = this.execFlows(actionName, "PL02", vos);
		// 批量收回后业务逻辑
		return res;
	}

	@Override
	public AggProUpdateHVO[] callbackSAVEBASE(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return null;
		}
		return this.saveAggProUpdateHVO(vos);

	}

	@Override
	public AggProUpdateHVO[] callbackSAVE(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return null;
		}
		// 同步单据状态和审批状态(只有提交时候需要手动设置审批状态。其余审批完后审批状态都已更新)
		Arrays.stream(vos).forEach(v -> {
			v.getParent().setAttributeValue("approvestatus", BillStatusEnum.COMMIT.toIntValue());
		});
		return this.saveAggProUpdateHVO(vos);

	}

	@Override
	public AggProUpdateHVO[] callbackUNSAVE(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return null;
		}
		// modify by wy
		SJXMUtil.callbackUNAPPROVEAggProUpdateHV(vos);
		return this.saveAggProUpdateHVO(vos);

	}

	@Override
	public AggProUpdateHVO[] callbackAPPROVE(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return null;
		}
		// modify by wy
		SJXMUtil.callbackAPPROVEAggProUpdateHV(vos);
		return this.saveAggProUpdateHVO(vos);

	}

	@Override
	public AggProUpdateHVO[] callbackUNAPPROVE(AggProUpdateHVO... vos) throws BusinessException {
		if (ArrayUtils.isEmpty(vos)) {
			return null;
		}
		// modify by wy
		return this.saveAggProUpdateHVO(vos);

	}
	@Override
	public BillCodeContext getBillCodeContext(String coderuleid) throws BusinessException {
		return super.getBillCodeContext(coderuleid);
	}

	@Override
	public BillCodeContext getBillCodeContext(String coderuleid, String pkgroup, String pkorg)
			throws BusinessException {
		return super.getBillCodeContext(coderuleid, pkgroup, pkorg);
	}
}
